﻿///<reference path="../../jquery-1.3.2-vsdoc.js" />
///<reference path="../Shell/Base.js" />
(function($, epi) {
    epi = epi || {};
    epi.dashboard = epi.dashboard || {};
    epi.dashboard.manager = epi.dashboard.manager || {};

    epi.dashboard.manager.tabView = function() {
        var pub = {};

        var _sharedResourceKey = "EPiServer.Shell.Resources.Texts";
        var _dashboardResourceKey = "EPiServer.Shell.UI.Views.Dashboard.Resources";

        pub.init = function() {
            /// <summary>
            ///     Initialization of epi.dashboard.manager.tabView functionality
            /// </summary>
            _tabId = null;
            _tabIndex = -1;
            _isAddingTab = false;
            _isGadgetMoving = false;

            // "Tabify" dashboardTabs and bind events to when user clicks add button (panel is shown) and when user chooses to edit a tab.
            _tabView = $("#dashboardTabs")
                            .epiTabView({
                                editable: true,
                                addButton: true,
                                removable: true,
                                addButtonText: epi.shell.resource.get(_dashboardResourceKey, "TabAddButtonText"),
                                addButtonTitle: epi.shell.resource.get(_dashboardResourceKey, "TabAddButtonDescription"),
                                menuText: epi.shell.resource.get(_sharedResourceKey, "Menu"),
                                deleteText: epi.shell.resource.get(_sharedResourceKey, "Delete"),
                                editText: epi.shell.resource.get(_sharedResourceKey, "Edit"),
                                tabPanelContainerClass: "epi-dashboardTabPanelContainer",
                                tabPanelClass: "epi-dashboardTabPanel"
                            })
                            .bind("epitabaddshow", _addTab)
                            .bind("epitabedit", _editTab)
                            .bind("epitabremove", _removeTab)
                            .bind("epitabrestore", _restoreTab)
                            .bind("epitabselect", _selectTab)
                            .bind("epigadgetbegindrag", _gadgetBeginDrag)
                            .bind("epigadgetenddrag", _gadgetEndDrag)
                            .bind("epitabvisibilitychanged", _tabVisibilityChanged);

            // dashboardTabsform is the form used for editing or adding a tab.
            _dashboardTabsForm = $("#dashboardTabsForm")
                                    .bind("submit", _saveTab);
            _dashboardTabsForm.validate({ wrapper: "div" });

            _foldOutPanel = $("#dashboardTabsForm > div")
                                .epiFoldOutPanel({
                                    autoOpen: false,
                                    panelHeaderText: epi.shell.resource.get(_dashboardResourceKey, "TabFormPanelCaption"),
                                    collapseButtonText: epi.shell.resource.get(_sharedResourceKey, "Close"),
                                    collapseButtonDescription: epi.shell.resource.get(_dashboardResourceKey, "FoldOutPanelCollapseDescription")
                                })
                                .bind("epifoldoutpanelcollapse", _collapseFoldOut)
                                .bind("epifoldoutpanelcollapse", epi.shell.layout.reportChanges)
                                .bind("epifoldoutpanelexpand", epi.shell.layout.reportChanges);

            _saveButton = $("#dashboardTabsForm_saveButton", _dashboardTabsForm)
                            .click(_saveTab);

            $("#dashboardTabsForm_cancelButton", _dashboardTabsForm).click(function() { _foldOutPanel.epiFoldOutPanel("collapse"); });

            _tabNameInput = $("#dashboardTabsForm_tabName", _dashboardTabsForm);

            _isLayoutsLoaded = false;

            _addGadgetPanel = $("#AddGadgetPanel");
            _addGadgetButton = $("#AddGadgetButton");

        };

        // variables set when initializing.
        var _tabView, _dashboardTabsForm, _foldOutPanel, _saveButton, _tabNameInput, _tabId, _tabIndex, _undoTabIndex, _isAddingTab, _layoutList, _isLayoutsLoaded, _addGadgetButton, _addGadgetPanel;

        var _gadgetBeginDrag = function(e) {
            _isGadgetMoving = true;
        };

        var _gadgetEndDrag = function(e) {
            _isGadgetMoving = false;
        };

        var _errorHandler = function(xmlHttpRequest, status, errorThrown) {
            /// <summary>
            ///    Common error handler for ajax requests in dashboard tabView.
            /// </summary>
            _setErrorMessage(epi.shell.resource.get(_dashboardResourceKey, "ErrorTabError"), xmlHttpRequest);
        };

        var _setErrorMessage = function(message, xmlHttpRequest) {
            epi.dashboard.manager.feedback.epiFeedback("setErrorMessage", message, xmlHttpRequest.responseText);
        }

        var _tabVisibilityChanged = function(e, args) {
            var gadgets = $(".epi-gadget", args.tab.panel);
            gadgets.each(function(i, gadgetDiv) {
                epi.gadget.visibilityChanged(gadgetDiv, args.isVisible);
            });
            if (args.isVisible) {
                _enableAddGadget();
            }
        };

        var _selectTab = function(e, args) {
            //If we allready has loaded the content, don't do it again
            var panel = $(args.panel);
            if (panel.children().length === 0) {
                //TODO: Verify that this is still needed after we have moved the Add Tab
                var tabId = args.tab.attr("id").replace(/epiTab/, "");
                if (tabId === "0") {
                    return;
                }
                _updateTabContent(tabId, args.index, function() {
                    if (_isGadgetMoving) {
                        epi.dashboard.manager.gadget.move.initGadgetDropzones();
                    }
                });
            }
            _tabIndex = args.index;
            _foldOutPanel.hide();
            epi.shell.layout.reportChanges();
        }

        var _addLayouts = function(successFunction) {
            /// <summary>
            ///    Adds layouts to the add/edit tab form. 
            /// </summary>
            var successHandler = function(data) {
                var iconurl, name, description, id, item, image, span, layout;
                for (layout in data.layouts) {
                    iconurl = data.layouts[layout].iconUrl;
                    name = data.layouts[layout].name;
                    id = "layoutId_" + data.layouts[layout].id;
                    description = data.layouts[layout].description;
                    item = $("<div/>").addClass("epi-Content-Container")
                        .attr("id", id);
                    $("<img/>").attr("src", iconurl).addClass("epi-itemList-thumb")
                        .attr("alt", "")
                        .appendTo(item);
                    $("<div/>").append($("<span/>").text(name).addClass("epi-itemList-link"))
                        .appendTo(item);
                    _layoutList.epiItemList("addItem", item);

                    successFunction();
                }
            };

            epi.shell.addToAjaxQueue({
                url: epi.shell.routes.getActionPath({ controller: 'Dashboard', action: 'GetTabLayouts' }),
                type: "get",
                dataType: "json",
                data: {},
                error: function(xmlHttpRequest, status, errorThrown) {
                    _setErrorMessage(epi.shell.resource.get(_dashboardResourceKey, "ErrorAddTabLayout"), xmlHttpRequest);
                },
                success: successHandler
            });
        };

        var _addTab = function(e, args) {
            /// <summary>
            ///     Handler for dashboard tabView "epitabaddshow" event
            ///     Is called when user clicks "Add button" in dashboard tabView.
            /// </summary>
            /// <param name="e" type="Event">
            ///     Event object.
            /// </param>
            /// <param name="ui" type="object">
            ///     Object exposed to all event handlers of epiTabView events (contains ui.tab, ui.panel and ui.index).
            /// </param>
            var tabNameNew = epi.shell.resource.get(_dashboardResourceKey, "TabNameNew");
            _isAddingTab = true;
            _tabIndex = args.index;
            _tabId = "{00000000-0000-0000-0000-000000000000}";
            _tabNameInput.val(tabNameNew);

            _tabNameInput.focus(function(e) {
                if (_tabNameInput.val() === tabNameNew) {
                    _tabNameInput.val("");

                }
            });
            _tabNameInput.blur(function(e) {
                if (_tabNameInput.val() === "") {
                    _tabNameInput.val(tabNameNew);

                }
            });
            _showForm(args.panel, function() { _layoutList.epiItemList('setSelectedIndex', 0); });
            _saveButton.val(epi.shell.resource.get(_sharedResourceKey, "Add"));
            _disableAddGadget();
        };

        var _editTab = function(e, args) {
            /// <summary>
            ///     Handler for dashboard tabView "epitabedit" event
            ///     Is called when user calls "Edit" of a tab in dashboard tabView.
            /// </summary>
            /// <param name="e" type="Event">
            ///     Event object.
            /// </param>
            /// <param name="ui" type="object">
            ///     Object exposed to all event handlers of epiTabView events (contains ui.tab, ui.panel and ui.index).
            /// </param>

            _tabIndex = args.index;
            _isAddingTab = false;
            _tabId = args.tab.attr("id").replace(/epiTab/, "");

            _disableAddGadget();

            var successHandler = function(data) {

                _showForm(args.panel, function() { _setSelectedLayout(data.layoutId); });
                _saveButton.val(epi.shell.resource.get(_sharedResourceKey, "Save"));
                _tabNameInput.val(data.name);
            };

            epi.shell.addToAjaxQueue({
                url: epi.shell.routes.getActionPath({ controller: 'Dashboard', action: 'GetTabData' }),
                type: "GET",
                dataType: "json",
                data: { tabId: _tabId },
                error: _errorHandler,
                success: successHandler
            }, { keepFeedback: true });
        };

        var _setSelectedLayout = function(layoutId) {
            /// <summary>
            ///    Sets the selected layout when editing a tab.
            /// </summary>
            /// <param name="layoutId" type="Guid">
            ///     The Id of the seleced Layout
            /// </param>
            _loadLayouts();
            var layoutArray = _layoutList.epiItemList('getAllListItems');
            var layoutIndex, currentLayoutId, resultIndex;

            resultIndex = 0;
            for (layoutIndex in layoutArray) {
                currentLayoutId = $(".epi-Content-Container", layoutArray[layoutIndex]).attr('id');
                if (currentLayoutId.replace("layoutId_", "") === layoutId) {
                    resultIndex = layoutIndex;
                    break;
                }
            }
            _loadLayouts();
            _layoutList.epiItemList('setSelectedIndex', resultIndex);
        };

        var _saveTab = function(e) {
            /// <summary>
            ///     Saves a tab, either updating an existing or adding a new depending on user interaction.
            ///     Event handler for dashboardTabsForm save button.
            /// </summary>
            /// <param name="e" type="Event">
            ///     Event object. Not used.
            /// </param>

            if (!_dashboardTabsForm.valid()) {
                e.preventDefault();
                return;
            }

            var data = {
                tabId: _tabId,
                name: _tabNameInput.val(),
                layoutId: $(".epi-Content-Container", _layoutList.epiItemList('getSelectedListItem')).attr('id').replace("layoutId_", "")
            };

            var successHandler = function(data) {
                if (_isAddingTab) {
                    _tabIndex = _tabView.epiTabView("length");
                    _tabView.epiTabView("add", "#panelId" + data.tabId, data.tabName, "epiTab" + data.tabId);
                } else {
                    _tabView.epiTabView("setTabName", data.tabName, _tabIndex);
                    _triggerUnloadForGadgetsInTab();
                }

                _updateTabContent(data.tabId, _tabIndex);
                _switchTabFocus();
            };

            epi.shell.addToAjaxQueue({
                url: _dashboardTabsForm.attr("action"),
                type: "POST",
                dataType: "json",
                data: data,
                error: function(xmlHttpRequest, status, errorThrown) {
                    _setErrorMessage(epi.shell.resource.get(_dashboardResourceKey, "ErrorSaveTab"), xmlHttpRequest);
                },
                success: successHandler
            });

            e.preventDefault();
        };

        var _removeTab = function(e, args) {
            /// <summary>
            ///     Handler for dashboard tabView "epitabremove" event
            ///     Is called when user calls "Remove" of a tab in dashboard tabView.
            /// </summary>
            /// <param name="e" type="Event">
            ///     Event object.
            /// </param>
            /// <param name="ui" type="object">
            ///     Object exposed to all event handlers of epiTabView events (contains ui.tab, ui.panel and ui.index).
            /// </param>

            if (!confirm(epi.shell.resource.get(_dashboardResourceKey, "ConfirmDeleteTab"))) {
                return false;
            }
            var tabId = args.tab.attr("id").replace(/epiTab/, "");
            _undoTabIndex = args.index;
            _triggerUnloadForGadgetsInTab();

            epi.dashboard.manager.feedback.epiFeedback("setMessage", epi.shell.resource.get(_dashboardResourceKey, "TabRemovedMessage"),
                {
                    UndoButton: {
                        text: epi.shell.resource.get(_sharedResourceKey, "Undo"),
                        description: epi.shell.resource.get(_dashboardResourceKey, "TabRemovedUndoDescription"),
                        click: function(e) {
                            $('#dashboardTabs').trigger('epitabrestore', { tabId: tabId });
                        },
                        tabIndex: 0
                    }
                });
            epi.dashboard.manager.feedback.epiFeedback("transferToFeedback", args.panel);

            var successHandler = function(data) {
                _foldOutPanel.hide();
                epi.shell.layout.reportChanges();
            };

            epi.shell.addToAjaxQueue({
                url: epi.shell.routes.getActionPath({ controller: 'Dashboard', action: 'RemoveTab' }),
                type: "POST",
                dataType: "json",
                data: { tabId: tabId },
                error: function(xmlHttpRequest, status, errorThrown) {
                    _setErrorMessage(epi.shell.resource.get(_dashboardResourceKey, "ErrorDeleteTab"), xmlHttpRequest);
                },
                success: successHandler
            }, { keepFeedback: true });
        };

        var _restoreTab = function(e, args) {
            /// <summary>
            ///     Handler for dashboard tabView "epitabrestore" event
            ///     Is called when user calls "Undo" of a tab removed from dashboard tabView.
            /// </summary>
            /// <param name="e" type="Event">
            ///     Event object.
            /// </param>
            /// <param name="ui" type="object">
            ///     Object exposed to all event handlers of epiTabView events (contains ui.tab, ui.panel and ui.index).
            /// </param>           

            var successHandler = function(data) {
                var tab = $("#epiTab" + args.tabId);
                _tabView.epiTabView("add", "#panelId" + args.tabId, data.name, "epiTab" + args.tabId, _undoTabIndex);
                _tabIndex = _undoTabIndex;
                _switchTabFocus();


                var updateTabContentCallback = function() {
                    var transferCallback = function() {

                        $(this).hide();
                        _tabIndex = _undoTabIndex = null;
                    };
                    epi.dashboard.manager.feedback.epiFeedback("transferFromFeedback", "#panelId" + args.tabId, transferCallback);
                };
                _updateTabContent(args.tabId, _undoTabIndex, updateTabContentCallback);
            };

            epi.shell.addToAjaxQueue({
                url: epi.shell.routes.getActionPath({ controller: 'Dashboard', action: 'RestoreTab' }),
                type: "POST",
                dataType: "json",
                data: { tabId: args.tabId },
                error: _errorHandler,
                success: successHandler
            });
        };

        var _showForm = function(panel, successFunction) {
            /// <summary>
            ///     Shows tab configuration form in supplied tab panel.
            /// </summary>
            /// <param name="panel" type="jQuery object">
            ///     The tab panel where the form is to be shown.
            /// </param>            
            _dashboardTabsForm.insertBefore(panel.parent());
            _foldOutPanel.epiFoldOutPanel("expand");

            _loadLayouts(successFunction);
        };

        var _loadLayouts = function(successFunction) {
            if (!_isLayoutsLoaded) {
                _isLayoutsLoaded = true;
                $("<label for='tabLayoutList'></label>")
                    .text(epi.shell.resource.get(_dashboardResourceKey, "TabFormLayoutLabel"))
                    .appendTo(".epi-dashboardTabLayout>.epi-dashboardTabContent", _foldOutPanel);

                _layoutList = $("<ul id='tabLayoutList' class='epi-itemList'></ul>")
                    .appendTo(".epi-dashboardTabLayout>.epi-dashboardTabContent", _foldOutPanel)
                    .epiItemList({ buttons: {
                        selectButton: {
                            text: epi.shell.resource.get(_sharedResourceKey, "Select"),
                            description: epi.shell.resource.get(_dashboardResourceKey, "TabFormLayoutSelectText"),
                            buttonClass: "epi-iconToolbar-selectable",
                            tabindex: -1
                        }
                    },
                        listItemSelectedClass: "epi-itemList-content",
                        listItemButtonClass: "epi-iconToolbar-selectable",
                        listItemButtonSelectedClass: "epi-iconToolbar-selected"
                    });

                _addLayouts(successFunction);
            }
            else {
                if (typeof successFunction === "function") {
                    successFunction();
                }
            }
        };

        var _updateTabContent = function(tabId, index, callback) {
            /// <summary>
            ///     Get the tab content (html) from the server for supplied tabId and
            ///     replaces whatever content the       apanel has at the moment.
            /// </summary>
            /// <param name="tabId" type="String">
            ///     String in form of a Guid indicating a tab id.
            /// </param>
            /// <param name="index" type="Integer">
            ///     The index of the tab we want to affect.
            /// </param>


            var successHandler = function(data) {

                _tabView.epiTabView("replacePanelContent", data, index);
                epi.shell.runInitFunctions();
                if (typeof callback === "function") {
                    callback();
                }
                epi.shell.layout.reportChanges();
            };

            epi.shell.addToAjaxQueue({
                url: epi.shell.routes.getActionPath({ controller: 'Dashboard', action: 'GetTabContent' }),
                type: "GET",
                dataType: "html",
                data: { tabId: tabId },
                error: _errorHandler,
                success: successHandler
            });
        };

        var _switchTabFocus = function() {
            /// <summary>
            ///     Switches tab focus if we currently selected tab is the AddButton tab
            ///     which also causes epiTabView to open corresponding panel.
            /// </summary>
            _tabView.epiTabView("select", _tabIndex);
        };

        var _collapseFoldOut = function() {
            if (_tabIndex == _tabView.epiTabView("length")) {
                _tabIndex = 0;
            }
            _switchTabFocus();
            _dashboardTabsForm.validate().resetForm();
        };

        var _disableAddGadget = function() {
            _addGadgetPanel.epiFoldOutPanel("collapse");
            _addGadgetButton.attr("disabled", "disabled");
            _addGadgetButton.addClass("epi-button-disabled");
        };

        var _enableAddGadget = function() {
            _addGadgetButton.removeAttr("disabled");
            _addGadgetButton.removeClass("epi-button-disabled");
        };

        var _triggerUnloadForGadgetsInTab = function() {
            // informs all gadgets about unload
            var curTabPanel = _tabView.epiTabView("getTabPanel", _tabIndex);
            var gadgets = $(".epi-gadget", curTabPanel);
            gadgets.each(function(i, gadgetDiv) {
                epi.gadget.unload(gadgetDiv);
            });
        };

        return pub;
    } ();

})(epiJQuery, epi);
